package spacegame;
/**
 * @author Pucella
 *
 */
public class MapLib {
  public static void displayArtifacts(Map m) {
    FuncIterator<Artifact> temp = m.getFuncIterator();
    while (temp.hasElement()) {
      System.out.println("  " + temp.current().toString());
      temp = temp.advance();
    }
  }
  
  public static void drawMap(Map m) {
    FuncIterator<Artifact> temp = m.getFuncIterator();
    int xmax = m.size().xPos();
    int ymax = m.size().yPos();
    if (xmax < 1 || ymax < 1)
      throw new IllegalArgumentException("Size of map < 1");
    char drawing[][] = new char[xmax][ymax];
    for (int i = 0; i < xmax; i++)
      for (int j = 0; j < ymax; j++)
        drawing[i][j] = '.';
    while (temp.hasElement()) {
      drawing[temp.current().position().xPos()]
             [temp.current().position().yPos()] = temp.current().display();
      temp = temp.advance();
    }
    System.out.println("");
    for (int j = ymax - 1; j >= 0; j--) {
      System.out.print("  ");
      for (int i = 0; i < xmax; i++)
        System.out.print(drawing[i][j] + " ");
      System.out.println("");
    }
    System.out.println("");
  }
  
  public static Map moveArtifact(Map m, Artifact a, int dx, int dy) {
    Option<Movable> ma = a.movable();
    if (ma.isNone()) {
      System.out.println("Cannot move artifact " + a);
      return m;
    }
    System.out.println("Attempting to move " + ma.valOf() + " by (" + dx + ","
                       + dy + ")");
    Coord c = ma.valOf().position().move(dx, dy);
    if (!(c.within(Coord.create(0, 0), m.size().move(-1, -1)))) {
      System.out.println("Final position out of bounds");
      return m;
    }
    Option<Artifact> target = m.findArtifactByPosition(c);
    if (target.isNone()) {
      System.out.println("Done");
      return m.moveArtifact(ma.valOf(), dx, dy);
    }
    System.out.println("Final position already occupied by " + target.valOf());
    return m;
  }
  
  public static Map fireAtArtifact(Map m, Artifact a, int dx, int dy) {
    Option<Energized> ea = a.energized();
    if (ea.isNone()) {
      System.out.println("Cannot fire with " + a);
      return m;
    }
    System.out.println("Firing from " + a + " to (" + dx + "," + dy + ")");
    Coord c = a.position().move(dx, dy);
    if (!(c.within(Coord.create(0, 0), m.size().move(-1, -1)))) {
      System.out.println("Final target position out of bounds");
      return m;
    }
    Option<Artifact> target = m.findArtifactByPosition(c);
    if (target.isNone()) {
      System.out.println("No target at final position");
      return m;
    }
    Option<Energized> etarget = target.valOf().energized();
    if (etarget.isNone()) {
      System.out.println("No effect on target");
      return m;
    }
    Artifact result = etarget.valOf().addEnergy(-10);
    Option<Energized> eresult = result.energized();
    if (eresult.valOf().energy() == 0) {
      System.out.println("Target destroyed");
      return m.removeArtifact(target.valOf());
    }
    System.out.println("Target takes a hit");
    return m.replaceArtifact(target.valOf(), result);
  }
}
